package mybatis.session;

import mybatis.config.Configuration;
import mybatis.executor.DefaultExecutor;
import mybatis.executor.Executor;
import mybatis.mapper.MapperHandler;
import mybatis.mapper.MapperStatement;

import java.lang.reflect.Proxy;
import java.util.List;
import java.util.Map;

/**
 * @author cg
 * @date 2023/6/20 16:13
 * sql的执行代理者，包含执行器和配置类
 */
public class SqlSession {
    //sql配置类
    private Configuration configuration;

    //sql执行器
    private Executor executor;

    public SqlSession(Configuration configuration) {
        this.configuration = configuration;
        executor = new DefaultExecutor();
    }

    /**
     * 查询一条数据
     * @param statementId 执行mapper的唯一标识
     * @param parameters 执行方法的参数
     * @return 查询结果
     * @param <T>
     */
    public <T> T selectOne(String statementId, Map<String, Object> parameters) {
        List<T> selectList = this.selectList(statementId, parameters);
        return (selectList != null && !selectList.isEmpty()) ? selectList.get(0) : null;
    }
    /**
     * 查询所有的数据
     * @param statementId 执行mapper的唯一标识
     * @param parameters 执行方法的参数
     * @return 查询结果
     * @param <E>
     */
    public <E> List<E> selectList(String statementId, Map<String, Object> parameters) {
        MapperStatement mapperStatement = configuration.getMapperStatement(statementId);
        return executor.query(mapperStatement, parameters);
    }

    /**
     * 更新数据库数据
     * @param statementId
     * @param parameters
     */
    public Integer update(String statementId, Map<String, Object> parameters) {
        MapperStatement mapperStatement = configuration.getMapperStatement(statementId);
        return executor.update(mapperStatement, parameters);
    }
    //返回mapper代理对象
    @SuppressWarnings("unchecked")
    public <T> T getMapper(Class<?> mapperInterface) {
        return (T) Proxy.newProxyInstance(this.getClass().getClassLoader(),
                new Class[]{mapperInterface},
                new MapperHandler(this,mapperInterface));
    }

    public Configuration getSqlConfig() {
        return configuration;
    }
}
